Creating a REST Service for a SQL Database

Description

Create a REST API to access your SQL Database using the REST Service genie.

Discussion

When you create a new REST API, the REST Genie can be used to create a REST API to expose data in a SQL database. The API will allow you to query the data in a table (returning the results in a JSON format) and to update, insert and delete records. The genie automatically creates the REST API definition and the Xbasic required for the REST API. The generated code supports authentication of each endpoint using an API key.

While te REST API generated by the genie can be used "as is", the primary purpose of the genie is to give you a starting point for building your own custom API.

In order to use the genie, set focus to the Web Services category on the Web Control Panel and then click the New button.

images/restapigenie1.jpg

Click the Create a new definition to create a REST service button.

images/restapigenie2.gif

Click the Use Genie to Create REST Service to Expose Database Tables button.

images/restapigenie3.jpg

This will open the genie, as shown below:

images/restapigenie4.jpg
  1. Specify the connection string to the database that contains the tables you want to expose.

  2. Select the tables/views you want to expose.

  3. For each selected table or view, select the operations you want to allow.

  4. Name the service.

  5. Finally, click the OK button to create the service - An Xbasic class and a Service definition will be generated.

For each table/view the following operations are available:

Operation
Description
Select

Allows you to select data from a table. The data is returned in JSON format. You can specify the column list, an optional WHERE clause, an optional ORDER BY clause, an optional set of arguments that can be used in the WHERE clause, a optional page size and and optional page number. If you don't specify the page size all records that match the WHERE clause are returned. See below for more information on how to use arguments.

Update

Allows you to update one or more records. The fields that are updated are specified by a comma delimited list of field name=value pairs. For example:

firstname=Fred,lastname=Jones,city=Boston

When specifying the value for each field, you can use arguments. If you use arguments, you must also supply the argument values. For example:

firstname=:c_fname,dateOfBirth=:dob

The arguments for the expression above are shown below:

c_fname=Fred,d_dob=12/18/1972

When updating a record, the WHERE clause defining which record to update is required. Returns a count of the number of records that were updated.

Insert

Allows you to create a new record. Take a comma delimited list of field name=value pairs:

firstname=Fred,lastname=Jones,city=Boston

When specifying the value for each field, you can use arguments. If you use arguments, you must also supply the argument values. For example:

firstname=:c_fname

The arguments for the expression above are shown below:

c_fname=Fred

If the table has an auto-increment primary key, returns the primary key of the record that was inserts.

Delete

Allows you to delete a record from the table. Takes a WHERE clause and an optional set of arguments that can be used in the WHERE clause.

Schema

Returns a list of fields in the table with the field type and size for each field.

images/restapigenie5.jpg

Once you click the OK button, the service is created. The genie creates a file with the name of the service and a .a5svc extension (this is the service definition), and another file called sqlcrud.<name of the service>.a5xbclass. This file contains the Xbasic class that defines the code that is executed for each of the REST end points.

images/restapigenie6.jpg

After the service is created, you will be asked if you want to test the API.

images/restapigenie7.jpg

If you specify that you do want to test the API, the Development Server will be started (if it is not already running) and your browser will be opened showing the test page for the service.

The page shows all of the end points in your API.

images/restapigenie8.jpg

To test a particular end point, click the button to the left of the end point. For example, in the image below, the customers_select end point is being tested. This the end point that exposes the select operation for the customers table.

Since this is a POST end point, the POST body must be specified using a JSON format.

In the image shown below, the properties in the POST body have been specified:

Properties
Description
fields

A comma delimited list of fields that should be returned.

where

A WHERE clause that defines which records should be selected. Notice that the WHERE clause uses an argument, rather than specifying the country value directly (e.g. country=USA). Using arguments is recommended because it protects against SQL injection attacks.

order

An ORDER BY clause.

arguments

a comma delimited list of name=value pairs to define the value of each argument. Argument names must start with a single letter prefix followed by an underscore. The single letter prefix defines the argument data type. The available types are C (character), D (date), T (date/time), L (logical), N (numeric). For example:

n_age=30,d_dob=12/6/1972

pagesize

The number of records per page. If left blank all records that satisfy the WHERE clause are returned.

pagenumber

The page number. Only meaningful if pagesize is specified.

images/restapigenie9.jpg

When the click the Execute button, The Curl command used to make the API call is shown and the result of the API call is shown

images/restapigenie10.jpg

Understanding Arguments

Arguments can be used in place of literal values in name/value pair parameters and WHERE clauses. For example, the expression below is a WHERE clause that uses arguments.

fname=:c_firstname AND dob=:d_date1

This expression uses two arguments (c_firstname and d_date1). Notice that in the WHERE clause the argument name are prefixed with a colon (:).

The argument values are defined in a comma delimited list of name/value pairs. For example:

c_firstname=Fred,d_date=12/18/1972

Notice that each argument name must start with a single letter, followed by an underscore. The single letter defines the data type of the argument value. The available types are C (character), D (date), T (date/time), L (logical), N (numeric).

How to Enable Authentication

The generated service definition and Xbasic class include methods for authenticating access to the API, but the authentication is not turned on. The authentication is done by passing in an API key when the API request is made.

If you open the service definition (see image below), you will notice that each of the methods that are exposed in the API (indicated by the green icon) has a lock icon to the right indicating that the method requires authentication.

images/restgenie20.jpg

If you click on the Define Authentication Methods button in the Service Builder you will see that named authentication methods have been define for each of the exposed methods.

For example, a named authentication method called customers_select_authenticate as been defined.

images/restgenie21.jpg

If you edit the definition of the customers_select method (by double clicking on it in the Available Methods list) you will see that authentication has been turned on and that the customers_select_authenticate method has been selected as the method that will be called to authenticate access to the end point that exposes the customers_select method.

images/restgenie22.jpg

The definition for both the customers_select method and the customers_select_authenticate method are contained in the sqlcrud.<servicename>.a5xbclass file that was generated.

The generated authentication method is shown below. Notice that the apikey is marked as an optional argument in the function definition (apikey = "").

To turn authentication on for the customers_select end point, you would change the function definition for the customers_select_authenticate method so that the apikey argument is required and you would then write your own code to determine if the function should return 200 (allowed) or 401 (not allowed), based on the value of the apikey that was supplied.

function customers_select_authenticate as n (apikey = "")
'to enable authentication
'    1) change the function prototype to make apikey required
'       (e.g. function customersupdateauthenticate as n (apikey as c ) )
'    2) write code that determines if the apikey allows this action
'    3) if allowed, return 200, if not allowed, return 401
customers_select_authenticate = 200
end function

In order to supply the APIKey at the time the API is called you would need to supply its value in the query parameters for the API end point. For example:

http://127.0.0.1:10444/LivePreview/northwind.a5svc/customers_select?apikey=12345

If you prefer to supply the apikey in the request header, then you would edit the Authentication Method and change the setting for Arguments to header.

images/restapigenie30.jpg

Videos

Using a Genie to Expose Tables in a SQL Database

Alpha Anywhere has a powerful REST API feature that allows you to create REST APIs for many different tasks. A common use case for a REST API is to expose data that is stored in a SQL database. The REST API Genie makes it easy to create an API that allows data to be read from a SQL database as well as modified or added.

In this video, we show how how to use the Genie to create a REST API for a SQL database.

2019-06-13

See Also